package com.ambulance.project.biz.controller.pad;

import com.alibaba.fastjson.JSON;
import com.ambulance.common.exception.CustomException;
import com.ambulance.common.utils.DateUtils;
import com.ambulance.framework.MyRedisTemplate;
import com.ambulance.framework.web.domain.AjaxResult;
import com.ambulance.project.biz.entity.*;
import com.ambulance.project.biz.service.*;
import com.ambulance.project.manager.utils.DoctorAndNurseCommonUtil;
import com.ambulance.project.websockt.WebSocketServer;
import com.ambulance.utils.CommonUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/***
 *  @description
 *  @author zhao
 *  @date: 2020/4/16
 *  @version: v1.0
 */
@Api(tags = {"随车医生-调度相关接口"})
@RequestMapping(value = "/pad/v1/dispatch", method = RequestMethod.POST)
@Controller
public class PadDispatchController {

    @Autowired
    public WebSocketServer webSocketServer;
    @Autowired
    private DispatchService dispatchService;
    @Autowired
    private DoctorAndNurseCommonUtil padCommonUtil;
    @Autowired
    private MyCustomerService myCustomerService;
    @Autowired
    private DispatchNoticeService dispatchNoticeService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DispatchCaseService dispatchCaseService;
    @Autowired
    private MyRedisTemplate myRedisTemplate;
    @Autowired
    private CarDeviceService carDeviceService;
    @Autowired
    private DispatchDeviceService dispatchDeviceService;

    /**
     * 打卡
     *
     * @param
     * @param status
     * @return
     */
    @RequestMapping(value = "/sign")
    @ResponseBody
    @ApiOperation(value = "随车医生打卡", notes = "打卡", produces = "application/json")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "remark", value = "打卡备注", dataType = "string"),
            @ApiImplicitParam(name = "status", value = "调度状态 0接警，1出车，2通话指导，3到达现场，4上车转运，5发起会诊，6溶栓开始7溶栓结束，8到达医院", required = true, paramType = "form", dataType = "String"),
    })
    @Transactional
    public Object sign(
            @RequestParam(value = "status") Integer status,
            @RequestParam(value = "remark", required = false, defaultValue = "") String remark
    ) throws IOException {

        // 医生打卡
        Dispatch dispatch = padCommonUtil.getDispatch();
        if (CommonUtils.checkNull(dispatch)) {
            throw new CustomException("调度信息不存在");
        }

        Boolean isOver = dispatch.getIsOver().equals(1);
        if (isOver) {
            throw new CustomException("调度已经结束");
        }
        Integer currentStatus = dispatch.getStatus();
        if (status <= currentStatus) {
            throw new CustomException("已打卡");
        }
        if (status != currentStatus + 1 && (status != 8 && status != 2 && status != 5)) {
            throw new CustomException("不可跳跃打卡");
        }
        // 通过 status 判断
        switch (status) {
            case 1:
                dispatch.setLeaveHospTime(LocalDateTime.now());
                final DispatchCase dispatchCase = new DispatchCase();
                dispatchCase.setCaseStatus(1);
                dispatchCaseService.update(dispatchCase, new QueryWrapper<DispatchCase>().eq("dispatchID", dispatch.getDispatchID()));
                break;
            //指导
            case 2:
                dispatch.setGuideStart(LocalDateTime.now());
                dispatch.setGuideContent(remark);
                //todo 指导结束时间未获取
                break;
            //到达患者处
            case 3:
                dispatch.setArriveDestTime(LocalDateTime.now());
                dispatch.setArriveDestContent(remark);
                break;
            //上车转运
            case 4:
                checkCurrentStatus(status, currentStatus);
                dispatch.setLeaveDestTime(LocalDateTime.now());
                break;
            // 发起会诊
            case 5:
                dispatch.setTreatStart(LocalDateTime.now());
                dispatch.setTreatContent(remark);
                break;
            //溶栓开始
            case 6:
                dispatch.setMedicineStart(LocalDateTime.now());
                break;
            //溶栓结束
            case 7:
                dispatch.setMedicineEnd(LocalDateTime.now());
                break;
            //到达医院
            case 8:
                final DispatchCase dispatchCase1 = new DispatchCase();
                dispatchCase1.setCaseStatus(2);
                dispatchCaseService.update(dispatchCase1, new QueryWrapper<DispatchCase>().eq("dispatchID", dispatch.getDispatchID()));
                dispatch.setArriveHostTime(LocalDateTime.now());
                //释放班组资源
                myCustomerService.releaseSource(dispatch.getDispatchID(), 1);
                dispatch.setIsOver(1);
                //修改通知状态，让验证码不再生效
                QueryWrapper<DispatchNotice> noticeQueryWrapper = new QueryWrapper<>();
                noticeQueryWrapper.eq("dispatchID", dispatch.getDispatchID());
                DispatchNotice notice = new DispatchNotice();
                notice.setStatus(0);
                dispatchNoticeService.update(notice, noticeQueryWrapper);
                //计算出车时间和救治时间
                long seconds = Duration.between(dispatch.getDispatchTime(), LocalDateTime.now()).toMinutes();
                dispatch.setOnCarTime(seconds);

                long seconds2 = Duration.between(dispatch.getArriveDestTime(), LocalDateTime.now()).toMinutes();
                dispatch.setOnHelpTime(seconds2);

                // 统计车载设备数据
                if (!CommonUtils.checkNull(dispatch.getCarDeviceId())) {
                    final String[] split = dispatch.getCarDeviceId().split(",");
                    for (String value : split) {
                        final CarDevice carDeviceServiceById = carDeviceService.getById(value);
                        String reallyKey = "dispatch_data_time_" + dispatch.getDispatchID() + "_" + carDeviceServiceById.getSerial();

                        Map dispatch_data_time = myRedisTemplate.opsForHash().entries(reallyKey);
                        System.out.printf("获取redisKey:%s,Value:%s%n", reallyKey, JSON.toJSONString(dispatch_data_time));
                        if (!CommonUtils.checkNull(dispatch_data_time)) {
                            final DispatchDevice dispatchDevice = new DispatchDevice();

                            Object start = dispatch_data_time.get("start");
                            if (null == start) {
                                // 默认当前时间30分钟前
                                dispatchDevice.setStartTime(LocalDateTime.now().plusMinutes(30));
                            } else {
                                dispatchDevice.setStartTime(DateUtils.parseString(start.toString()));
                            }

                            Object end = dispatch_data_time.get("end");
                            // 若没有结束时间，则取当前打开时间
                            if (null == end) {
                                dispatchDevice.setEndTimes(LocalDateTime.now());
                            } else {
                                dispatchDevice.setEndTimes(DateUtils.parseString(dispatch_data_time.get("end").toString()));
                            }

                            dispatchDevice.setDeviceID(Integer.parseInt(value));
                            dispatchDevice.setDispatchID(dispatch.getDispatchID());
                            dispatchDeviceService.save(dispatchDevice);
                            System.out.println("-------------------------");
                            System.out.println("同步成功");
//                            myRedisTemplate.keys(reallyKey);
                            myRedisTemplate.expire(reallyKey, 100, TimeUnit.SECONDS);
                            // 删除本地调度存入redis的信息包括 调度-设备
//                            myRedisTemplate.delete("dispatch_hash_"+dispatch.getDispatchID());
                            myRedisTemplate.expire("dispatch_hash_" + dispatch.getDispatchID(), 100, TimeUnit.SECONDS);
                            // 设置过期时间

                        }
                    }
                }


                break;
            default:
                throw new CustomException("状态标识不正确");
        }

//        放入redis队列 队列名为调度id
//        redisTemplate.opsForList().leftPush("sign_status_change",dispatch.getDispatchID());
//            webSocketServer.sendInfo(dispatch.getCarID()+"","sign");
//            webSocketServer.send2AllInfo(dispatch.getCarID()+"");
//        WebSocketUtils.sendMessageAll(dispatch.getCarID()+"");
        webSocketServer.sendInfo(dispatch.getCarID() + "");

        dispatch.setStatus(status);
        dispatchService.updateById(dispatch);
        return AjaxResult.success();
    }

    private void checkCurrentStatus(Integer status, Integer current) {
        if (status > current + 1) {
            throw new CustomException("请重新确认打卡");
        }
    }


}
